import pandas as pd
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error, root_mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import SGDRegressor       # 随机梯度下降算法


# 一、正规方程法
def line_zc():
    # 1. 读取数据
    df = pd.read_excel("boston_house_prices.xlsx")

    # 2.数据预处理
    x_data = df.iloc[:, :-1]    # 获取到特征值
    y_data = df.iloc[:, -1]     # 获取到目标列

    # 3.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.2, random_state=922)

    # 4.特征方程
    # 4.1 特征预处理（标准化）
    transformer = StandardScaler()                  # 构建标准化对象
    x_train = transformer.fit_transform(x_train)    # 对训练特征值数据进行学习和转换

    # 5.模型构建
    model = LinearRegression()      # 使用普通的线性回归算法构建模型
    model.fit(x_train, y_train)     # 模型训练

    # 6.模型评估
    # 6.1 对测试值进行标准化处理
    x_test = transformer.transform(x_test)

    # 6.2 使用测试值对模型进行预测
    y_predict = model.predict(x_test)

    # 6.3 通过三种回归评估方法，得到他们各自的评估值
    print("MSE：",mean_squared_error(y_test, y_predict))
    print("MAE：",mean_absolute_error(y_test, y_predict))
    print("RMSE：",root_mean_squared_error(y_test, y_predict))


# 梯度下降法
def sgd_ml():

    # 1. 读取数据
    df = pd.read_excel("boston_house_prices.xlsx")

    # 2.数据预处理
    x_data = df.iloc[:, :-1]
    y_data = df.iloc[:, -1]

    # 3.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.2, random_state=922)

    # 4.特征方程
    # 4.1 特征预处理（标准化）
    transformer = StandardScaler()  # 构建标准化对象
    x_train = transformer.fit_transform(x_train)  # 对训练特征值数据进行学习和转换

    # 5.模型构建
    """
        learning_rate：学习率的变化策略。常见的参数值解释如下
            constant：学习率不发生变化，是一个固定值。值具体由eta0来设置
            invscaling：学习率按比例变小。eta0设置的学习率初始值
        eta0：学习率的值，也就是梯度下降公式中的α
    """
    model = SGDRegressor(learning_rate="constant",eta0=0.001)       # 使用 随机梯度下降算法 构建模型
    model.fit(x_train, y_train)  # 模型训练

    # 6.模型评估
    # 6.1 对测试值进行标准化处理
    x_test = transformer.transform(x_test)

    # 6.2 使用测试值对模型进行预测
    y_predict = model.predict(x_test)

    # 6.3 通过三种回归评估方法，得到他们各自的评估值
    print("MSE：", mean_squared_error(y_test, y_predict))
    print("MAE：", mean_absolute_error(y_test, y_predict))
    print("RMSE：", root_mean_squared_error(y_test, y_predict))


if __name__ == '__main__':
    line_zc()
    print("-"*66)
    sgd_ml()